<?php

namespace pmvc\template\smarty;

use pmvc\util\StringUtil;

use Smarty;
use Exception;
use pmvc\util\ReflectionUtil;

class SmartyUtil {

	public static function setCaching(&$smarty, $caching) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->setCaching(
				$caching===true ? Smarty::CACHING_LIFETIME_CURRENT : Smarty::CACHING_OFF);
		} else {
			$smarty->caching = $caching;
		}
	}

	public static function registerFunction(&$smarty, $name, $callback, $cacheable=TRUE, $cache_attrs=Array()) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerPlugin('function', $name, $callback, $cacheable, $cache_attrs);
		} else {
			$smarty->register_function($name, $callback, $cacheable, $cache_attrs);
		}
	}

	public static function registerObject(&$smarty, $name, &$object, $allowed_methods_properties=NULL,
			$format=NULL, $block_methods=NULL) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerObject($name, $object, $allowed_methods_properties, $format, $block_methods);
		} else {
			$smarty->register_object($name, $object, $allowed_methods_properties, $format, $block_methods);
		}
	}

	public static function getRegisteredObject(&$smarty, $name, $required=false) {
		$ret = null;
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$ret = $smarty->getRegisteredObject($name);
		} else {
			$ret = $smarty->get_registered_object($name);
		}
		if (!isset($ret) && $required===true) {
			throw new Exception("Unable to find required registered object: ".$name);
		}
		return $ret;
	}

	public static function registerBlock(&$smarty, $name, $impl, $cacheable=TRUE, $cache_attrs=NULL) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerPlugin('block', $name, $impl, $cacheable, $cache_attrs);
		} else {
			$smarty->register_block($name, $impl, $cacheable, $cache_attrs);
		}
	}

	public static function registerCompilerFunction(&$smarty, $name, $impl, $cacheable=TRUE) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerPlugin('compiler', $name, $impl, $cacheable);
		} else {
			$smarty->register_compiler_function($name, $impl, $cacheable);
		}
	}

	public static function registerModifier(&$smarty, $name, $impl) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerPlugin('modifier', $name, $impl);
		} else {
			$smarty->register_modifier($name, $impl);
		}
	}

	public static function registerOutputFilter(&$smarty, $impl) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerFilter('output', $impl);
		} else {
			$smarty->register_outputfilter($impl);
		}
	}

	public static function registerPostFilter(&$smarty, $impl) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerFilter('post', $impl);
		} else {
			$smarty->register_postfilter($impl);
		}
	}

	public static function registerPreFilter(&$smarty, $impl) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$smarty->registerFilter('pre', $impl);
		} else {
			$smarty->register_prefilter($impl);
		}
	}

	public static function addPluginDir(&$smarty, $dir) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->addPluginsDir($dir);
		} else {
			return $smarty->plugins_dir []= $dir;
		}
	}

	public static function setTemplateDir(&$smarty, $dir) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->setTemplateDir($dir);
		} else {
			return $smarty->template_dir = $dir;
		}
	}

	public static function setCompileDir(&$smarty, $dir) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->setCompileDir($dir);
		} else {
			return $smarty->compile_dir = $dir;
		}
	}

	public static function setConfigDir(&$smarty, $dir) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->setConfigDir($dir);
		} else {
			return $smarty->config_dir = $dir;
		}
	}

	public static function setCacheDir(&$smarty, $dir) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->setCacheDir($dir);
		} else {
			return $smarty->cache_dir = $dir;
		}
	}

	public static function setUseSubDirs(&$smarty, $val) {
		$smarty->use_sub_dirs = $val===true;
	}

	public static function getTemplateVar(&$smarty, $name, $required=false) {
		$ret = null;
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			$ret = $smarty->getTemplateVars($name);
		} else {
			$ret = $smarty->get_template_vars($name);
		}
		if (!isset($ret) && $required===true) {
			throw new Exception("Unable to find required template var: ".$name);
		}
		return $ret;
	}

	public static function getTemplateVars(&$smarty) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->getTemplateVars();
		} else {
			return $smarty->get_template_vars();
		}
	}

	public static function assignTemplateVars(&$smarty, array $vars) {
		$smarty->assign($vars);
	}

	public static function clearTemplateVars(&$smarty, array $vars) {
		if (is_subclass_of($smarty, 'Smarty_Internal_Data')) {
			return $smarty->clearAssign($vars);
		} else {
			$smarty->clear_assign($vars);
		}
	}

	public static function render(&$smarty, $template) {
		return $smarty->fetch($template);
	}

	public static function assertRequiredParameters(Array &$params, Array $names) {
		foreach ($names as $name) {
			if (!isset($params[$name])) {
				throw new Exception("Missing required parameter: ".$name);
			}
		}
	}

	public static function returnOrAssign(&$smarty, $params, $value, $assignKey="assign") {
		if (isset($params[$assignKey])) {
			self::assignTemplateVars($smarty, Array($params[$assignKey]=>$value));
		} else {
			return $value;
		}
	}

	public static function renderParamsAsAttributes(array $params, &$smarty) {
		 
		// get the form errors
		$errors = array_key_exists("errors", $params)
			? $params["errors"]
			: SmartyUtil::getTemplateVar($smarty, "formErrors");

		// if it's the object, get the error array
		if (ReflectionUtil::isInstance($errors, 'pmvc\mvc\controller\FormErrors')) {
			$errors = $errors->get();
		}
	
		// check for errors
		$field = isset($params["name"]) ? $params["name"] : null;
		$hasError = isset($field)
			&& isset($errors)
			&& isset($errors["fieldErrors"])
			&& isset($errors["fieldErrors"][$field])
			&& count($errors["fieldErrors"])>=0;
	
		// add error class
		if ($hasError && isset($params["errorClass"])) {
			$params["class"] = isset($params["class"]) ? $params["class"]." " : "";
			$params["class"] .= $params["errorClass"];
			unset($params["errorClass"]);
		}
	
		// build attribute html
		$ret = '';
		foreach ($params as $key => $value) {
			$ret .= ' '.preg_replace('/_/', '-', $key).'="'.htmlspecialchars($value).'"';
		}
	
		// return it
		return $ret;
	}

	public static function getSelectedOptions(array $params, &$smarty) {
	
		// get the request object
		$request = SmartyUtil::getRegisteredObject($smarty, "Request", true);
	
		// check for "selectedOptions" first
		$selectedOptions = (isset($params["selectedOptions"])) ? $params["selectedOptions"] : null;
	
		// override selected options with what's in the request
		if (isset($params["name"])
			&& $request->hasParameter($params["name"])) {
			$selectedOptions = $request->getParameter($params["name"]);
		}
	
		// turn them into an array
		if (isset($selectedOptions) && !is_array($selectedOptions)) {
			$selectedOptions = Array($selectedOptions);
		}
	
		// return it
		return $selectedOptions;
	}
}

?>